﻿using System.ComponentModel.DataAnnotations;

namespace MVVMtutorialAdvanced.Web
{
	public abstract class EntityBase<T> where T : EntityBase<T>
	{
		[Key]
		public virtual int Id { get; set; }

		public override bool Equals(object obj)
		{
			var other = obj as T;
			if (other == null)
				return false;

			var thisIsNew = Equals(Id, 0);
			var otherIsNew = Equals(other.Id, 0);

			if (thisIsNew && otherIsNew)
				return ReferenceEquals(this, other);

			return Id == other.Id;
		}

		private int? oldHashCode;
		public override int GetHashCode()
		{
			// onece we have a hash code we'll never change it
			if (oldHashCode.HasValue)
				return oldHashCode.Value;

			// when this instance is new we use the base hash code and remebre it
			// so a instance can never change its hash code
			var thisIsNew = Equals(Id, 0);

			if (thisIsNew)
			{
				oldHashCode = base.GetHashCode();
				return oldHashCode.Value;
			}
			return Id.GetHashCode();
		}

		public static bool operator == (EntityBase<T> lhs, EntityBase<T> rhs)
		{
			return Equals(lhs, rhs);
		}

		public static bool operator !=(EntityBase<T> lhs, EntityBase<T> rhs)
		{
			return !Equals(lhs, rhs);
		}
	}
}